#include "common.h"
#include "pcie_proce.h"
#include "util-files.h"
#include "sys_resource.h"

#ifdef     IF_NOEXIT_PCIE
#include<stdlib.h>
#include<time.h>
#endif

volatile int thread_recv_pcie_signal = 0;  //信号量, 用于检测当前线程间的状态 1.运行    0.结束
void thread_recv_pcie_data(PackWriteFile *cpwf) {
    prctl(PR_SET_NAME, "PCIE_DMA");
    // pthread_detach(pthread_self());     //设置当前线程为分离线程

    LOG_WARN("PCIE 数据采集开始 \n");
#ifdef     IF_NOEXIT_PCIE
    srand((unsigned)time(NULL));
#endif       
#ifdef  QUEUE_STATUS   
    LOG_INFO("BQUEUE LEN: %d \n", verifyQBoxLen(qBox));
#endif    
  
    BQueueBox *qBox = cpwf->qBox;
    PackWriteFile *pwf = NULL;
    BQueue *queue = NULL;
    int order;
    int channel_num;
    while (1) {
        /** 从PCIE获取数据, 这里应该先获取队列中的数据 */
        queue = mallocBQueue(qBox);

        if(NULL == queue) {
            
            // usleep(10*1000);   //挂载1毫秒, 释放 CPU 占用率

            if(!thread_recv_pcie_signal) {
                break;
            }
#ifdef  QUEUE_STATUS     
            LOG_INFO("#ERR: 队列池中没有可用的内存 \n");
#endif
            continue;
        }

        channel_num = get_pcieData(queue->rbuf, queue->blen);

/********************************/
        // size_t i = 0;
        // LOG_DEBUG("\n");
        // for (; i < queue->blen; i++)
        // {
        //     if(i % 16 == 0) {
        //         LOG_DEBUG("\n");
        //     }
        //     LOG_DEBUG(" %x", queue->rbuf[i]);
        // }
        // LOG_DEBUG("\n");
        
/********************************/



        if(channel_num == KT_WARN) {
            LOG_DEBUG("PCIE 采集数据结束 \n");
            break;
        }

        if(channel_num == KT_ERROR) {
            LOG_ERROR("#ERR: PCIE 采集数据异常结束 \n");
            break;
        }
#ifdef     IF_NOEXIT_PCIE
        //rand()%(b-a+1) + a 生成 [a, b] 范围的随机数
        channel_num = rand() % SIM_PCIE_NUM;             //[0~21] 
#endif

        /** 将通道信息赋值给 channel */
        queue->channel = channel_num;
        queue->type = QU_OPTI;
        queue->qlen = queue->blen;

        /** 将对应的通道放入对应的线程队列中 */
        order = GET_WRITE_THREAD_INDEX(channel_num);
        pwf = cpwf + order;

#ifdef  QUEUE_STATUS
        LOG_INFO("队列数: %d, queue: %p, pwf: %p, order: %d, FREE: %d, channel: %d \n", 
            PCIE_QUEUE_NUM, queue, pwf, order,
            (PCIE_QUEUE_NUM - getBusyNumBQueue(qBox->bQueue)), channel_num);
#endif
        // LOG_DEBUG("order: %d, pwf: %p, oqBox: %p \n", order, pwf, pwf->oqBox);
        if(KT_OK != inputOrderQueueEle(pwf->oqBox, queue)) {
            LOG_ERROR("数据队列已满, 通道 %d \n", channel_num);
        }
    }
}
